//
// Error codes and HRESULTS
//
// For all new error codes, please use the macro MAKE_AGENT_HRESULT instead of
// MAKE_HRESULT. This macro sets both the custom facility code of kFacilityPCAgent
// and the C bit (0x20000000) to indicate it is a customer code.

#ifndef LONGKEY_BASE_ERROR_H_
#define LONGKEY_BASE_ERROR_H_

#include <windows.h>

//
// Exception Codes.
//
#define EXCEPTION_IMPERSONATION_FAILED			0x01
#define EXCEPTION_REVERT_IMPERSONATION_FAILED	0x02

//
// HRESULT Functions.
//

// Returns the last error as an HRESULT or E_FAIL if last error is NO_ERROR.
// This is not a drop in replacement for the HRESULT_FROM_WIN32 macro.
// The macro maps a NO_ERROR to S_OK, whereas the function below maps a
// NO_ERROR to E_FAIL. Also, the macro is evaluating arguments multiple times.
HRESULT HRESULTFromLastError();

// Returns the http status_code as an HRESULT
HRESULT HRESULTFromHttpStatusCode(int status_code);

//
// HRESULTs.
//
// Top bit indicates success (0) or failure (1)
// 16 bits available for 'code' field at end

const ULONG kHresultCBit	= 0x20000000;
const ULONG kFacilityAgent	= 67;

#define MAKE_AGENT_HRESULT(sev,code)		\
	((HRESULT)(((ULONG)(sev) << 31)	|		\
	           kHresultCBit |				\
			   (kFacilityAgent << 16) |		\
			   ((ULONG)(code))))

#define CI_E_NOT_ENOUGH_DISK_SPACE			\
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0003)

// CI_E_INVALID_MANIFEST is returned when the manifest file is missing a
// required field or has some other kind of semantic error
#define CI_E_INVALID_MANIFEST                     \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0012)

// CI_E_XML_LOAD_ERROR is returned when MSXML can't load the document into DOM.
// It may be because the document is not well formed (tags, namespaces, etc)
#define CI_E_XML_LOAD_ERROR                       \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0013)

// CI_E_INVALID_ARG is returned when invalid command line arugment is specified
#define CI_E_INVALID_ARG                          \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x001B)

// CI_E_PROXY_AUTH_REQUIRED is returned when proxy authentication is required
#define CI_E_PROXY_AUTH_REQUIRED                  \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0028)

// CI_E_INVALID_PROXY_AUTH_SCHEME is returned when the proxy authentication
// scheme is unknown or not supported
#define CI_E_INVALID_PROXY_AUTH_SCHEME            \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0029)

// CI_E_BITS_DISABLED is returned by the download manager when the BITS service
// is not enabled.
#define CI_E_BITS_DISABLED                        \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0030)

// CI_E_HTTPS_CERT_FAILURE is returned when the https connection fails.
// One cause of this is when the system clock is off by a significant
// amount which makes the server certificate appear invalid.
#define CI_E_HTTPS_CERT_FAILURE                   \
	MAKE_HRESULT(SEVERITY_ERROR, kFacilityAgent, 0x0035)

// Return values from Process::WaitUntilDeadOrInterrupt
// TODO Move this constants to the Process class. They do not look like
// error codes.
#define CI_S_PROCESSWAIT_DEAD                     \
	MAKE_HRESULT(SEVERITY_SUCCESS, kFacilityAgent, 0x0100)
#define CI_S_PROCESSWAIT_TIMEOUT                  \
	MAKE_HRESULT(SEVERITY_SUCCESS, kFacilityAgent, 0x0101)
#define CI_S_PROCESSWAIT_MESSAGE                  \
	MAKE_HRESULT(SEVERITY_SUCCESS, kFacilityAgent, 0x0102)

#define PCAGENT_E_RESOURCE_DLL_PATH_EMPTY          \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x605)

#define PCAGENT_E_NO_ARGS                          \
	MAKE_AGENT_HRESULT(SEVERITY_ERROR, 0x606)

#define PCAGENT_E_PATH_APPEND_FAILED               \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x709)



// Command line parse custom error codes.
#define PCAGENT_COMMANDLINE_E_NO_SCENARIO_HANDLER \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xC00)
#define PCAGENT_COMMANDLINE_E_NO_SCENARIO_HANDLER_MATCHED \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xC01)

// Signatures error codes.
#define SIGS_E_INVALID_PFX_CERTIFICATE            \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0200)
#define SIGS_E_INVALID_DER_CERTIFICATE            \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0201)
#define SIGS_E_INVALID_PASSWORD                   \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0202)
#define SIGS_E_INVALID_KEY_TYPE                   \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0203)
#define SIGS_E_INVALID_SIGNATURE                  \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0204)

#define AGENT_E_NETWORK_FIRST                            \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x2000)

// Http Status Code 401 -- Unauthorized.
#define AGENT_E_NETWORK_UNAUTHORIZED                     \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x2191)

#define AGENT_E_NETWORK_LAST                             \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x23FF)

#define LONGKEY_XML_E_STRTOUINT                   \
	MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x300)


// This is the end of the range for FACILITY_ITF errors. Do not define errors
// below.

// Gets or sets the value of the extra code. Use this feature to convey
// additional error information in canary builds.
int error_extra_code1();
void set_error_extra_code1(int extra_code);


#endif	// LONGKEY_BASE_ERROR_H_